package com.devin.material.material_rfid_plugin

import android.util.Log
import com.rscja.deviceapi.RFIDWithUHF
import com.rscja.deviceapi.entity.SimpleRFIDEntity
import com.rscja.deviceapi.exception.ConfigurationException
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar

/** MaterialRfidPlugin */
public class MaterialRfidPlugin: FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var channel : MethodChannel

  val INIT = "init"
  val FREE = "free"
  val READ_DATA = "readData"
  val READ_TAG = "readTag"
  val startInventoryTag = "startInventoryTag"
  val stopInventory = "stopInventory"
  val convertUiiToEPC = "convertUiiToEPC"

  override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), CHANNEL)
    channel.setMethodCallHandler(this);
  }

  // This static function is optional and equivalent to onAttachedToEngine. It supports the old
  // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
  // plugin registration via this function while apps migrate to use the new Android APIs
  // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
  //
  // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
  // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
  // depending on the user's project. onAttachedToEngine or registerWith must both be defined
  // in the same class.
  companion object {
    val CHANNEL = "material_rfid_plugin"
    @JvmStatic
    fun registerWith(registrar: Registrar) {
      val channel = MethodChannel(registrar.messenger(), CHANNEL)
      channel.setMethodCallHandler(MaterialRfidPlugin())
    }
  }

  override fun onMethodCall(call: MethodCall, result: Result) {
    Log.d("devin_zz", call.method)
    try {
      if (call.method == "getPlatformVersion") {
        result.success("Android ${android.os.Build.VERSION.RELEASE}")
      } else if (call.method == INIT) {
        result.success(RFIDWithUHF.getInstance().init())
      } else if (call.method == READ_DATA) {
        val accessPwd = call.argument<String>("accessPwd") //标签的ACCESS PASSWORD（4 byte）
        val bank = call.argument<String>("bank") ?: "DIGITAL_SIGNATURE"//标签的存储区
        val ptr = call.argument<Int>("ptr") ?: 0//起始地址的偏移量
        val cnt = call.argument<Int>("cnt") ?: 0//数据的长度（Word为单位，不能为0）
        val uii = call.argument<String>("uii") ?: "1"//标签的UII

        val bankEnum = when(bank){
          "DIGITAL_SIGNATURE" -> RFIDWithUHF.BankEnum.DIGITAL_SIGNATURE
          "RESERVED" -> RFIDWithUHF.BankEnum.RESERVED
          "TID" -> RFIDWithUHF.BankEnum.TID
          "UII" -> RFIDWithUHF.BankEnum.UII
          "USER" -> RFIDWithUHF.BankEnum.USER
          else -> RFIDWithUHF.BankEnum.DIGITAL_SIGNATURE
        }

        val data  = RFIDWithUHF.getInstance().readData(accessPwd, bankEnum, ptr, cnt, uii)

        if (data == null) {
          Log.d("devin_zz", "读取失败")
          result.error("INIT_ERR", "读取失败", null)
        } else {
          Log.d("devin_zz", "读取成功")
          result.success(data)
        }
      } else if (call.method == FREE) {
        result.success(RFIDWithUHF.getInstance().free())
      } else if (call.method == READ_TAG) {
        val tags = RFIDWithUHF.getInstance().readTagFromBuffer()
        Log.d("devin_zz", READ_TAG)
        val tag1 = try {
          tags[0]
        } catch (e: Exception){
          null
        }
        val tag2 = try {
          tags[1]
        } catch (e: Exception){
          null
        }
        val tag3 = try {
          tags[2]
        } catch (e: Exception){
          null
        }
        result.success(listOf(tag1, tag2, tag3))
      } else if (call.method == startInventoryTag) {
        val flagAnti = call.argument<Int>("flagAnti") ?: 0 //是否使用防碰撞识别功能,默认使用0
        val initQ = call.argument<Int>("initQ") ?: 1 //防碰撞识别过程的初始Q值，flagAnti为1时有效

        val data  = RFIDWithUHF.getInstance().startInventoryTag(flagAnti, initQ)
        result.success(data)
      } else if (call.method == stopInventory) {
        result.success(RFIDWithUHF.getInstance().stopInventory())
      } else if (call.method == convertUiiToEPC) {
        val uii = call.argument<String>("uii") ?: "1"//标签的UII
        val data  = RFIDWithUHF.getInstance().convertUiiToEPC(uii)

        if (data == null) {
          Log.d("devin_zz", "读取失败")
          result.error("INIT_ERR", "读取失败", null)
        } else {
          Log.d("devin_zz", "读取成功")
          result.success(data)
        }
      } else {
        result.notImplemented()
      }
    } catch (e: ConfigurationException) {
      e.printStackTrace()
      result.error("INIT_ERR", "初始化异常", e)
    }
  }

  override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }
}
